package csrpg;

import org.twgg.cssula.ConsoleTool;

class Role extends Thread{
    public char name;
    public int color;
    public int x,y, cycle;
    public Map map;
    protected boolean run = true;
    public Role(Map map, char name, int color, int cycle){
        this.map = map;
        this.name = name;
        this.color = color;
        this.cycle = cycle;
    }

    @Override
    public void run(){
    }
    
    protected void stopThread(){
        run = false;
    }
}

class Player extends Role{
    public Player(Map map, char name, int color, int cycle){
        super(map, name, color, cycle);
    }
    @Override
    public void run(){
        try {
            while (run) {
                Thread.sleep(cycle);
                synchronized (Game.lock) {
                    if(ConsoleTool.getKeyState('J')){
                        if (ConsoleTool.getKeyState('D') && !ConsoleTool.getKeyState('A') && !map.ground[y][x + 1].isBlock) map.add(new Bullet(map,'㊣',ConsoleTool.GREEN | ConsoleTool.BRIGHT, 50, 3), x+1, y);
                        else if (!ConsoleTool.getKeyState('D') && ConsoleTool.getKeyState('A') && !map.ground[y][x - 1].isBlock) map.add(new Bullet(map,'㊣',ConsoleTool.GREEN | ConsoleTool.BRIGHT, 50, 2), x-1, y);
                        else if (ConsoleTool.getKeyState('S') && !ConsoleTool.getKeyState('W') && !map.ground[y + 1][x].isBlock) map.add(new Bullet(map,'㊣',ConsoleTool.GREEN | ConsoleTool.BRIGHT, 50, 1), x, y+1);
                        else if (!ConsoleTool.getKeyState('S') && ConsoleTool.getKeyState('W') && !map.ground[y - 1][x].isBlock) map.add(new Bullet(map,'㊣',ConsoleTool.GREEN | ConsoleTool.BRIGHT, 50, 0), x, y-1);
                    }else{
                        int preX = x, preY = y;
                        // left and right
                        if (ConsoleTool.getKeyState('D') && !ConsoleTool.getKeyState('A') && !map.ground[y][x + 1].isBlock && map.ground[y][x + 1].regestedRole==null) x++;
                        else if (!ConsoleTool.getKeyState('D') && ConsoleTool.getKeyState('A') && !map.ground[y][x - 1].isBlock&& map.ground[y][x - 1].regestedRole==null) x--;
                        // up and down
                        if (ConsoleTool.getKeyState('S') && !ConsoleTool.getKeyState('W') && !map.ground[y + 1][x].isBlock&& map.ground[y + 1][x].regestedRole==null) y++;
                        else if (!ConsoleTool.getKeyState('S') && ConsoleTool.getKeyState('W') && !map.ground[y - 1][x].isBlock&& map.ground[y - 1][x].regestedRole==null) y--;

                        if(preX!=x || preY !=y) map.ground[preY][preX].regestedRole = null;
                    }
                    map.ground[y][x].regestedRole = this;
                }
            }
        } catch (Exception e) {
            ConsoleTool.cls();
            e.printStackTrace();
        }
    }
}

class NPC extends Role{
    public NPC(Map map, char name, int color, int cycle){
        super(map, name, color, cycle);
    }
    @Override
    public void run(){
        try{
            int orignX = x;
            int orignY = y;
            int action;
            while(run){
                Thread.sleep(cycle);
                synchronized (Game.lock) {
                    int preX = x, preY = y;
                    action = Game.rand.nextInt(5);
                    switch (action) {
                        case 0:
                            if (!map.ground[y][x + 1].isBlock && map.ground[y][x + 1].regestedRole==null && x <orignX+1) x++;
                            break;
                        case 1:
                            if (!map.ground[y][x - 1].isBlock && map.ground[y][x - 1].regestedRole==null && x > orignX-1) x--;
                            break;
                        case 2:
                            if (!map.ground[y + 1][x].isBlock && map.ground[y + 1][x].regestedRole==null && y < orignY+1) y++;
                            break;
                        case 3:
                            if (!map.ground[y - 1][x].isBlock && map.ground[y - 1][x].regestedRole==null && y > orignY-1) y--;
                            break;
                        default:
                            break;
                    }
                    if (preX != x || preY != y) {
                        map.ground[preY][preX].regestedRole = null;
                        map.ground[y][x].regestedRole = this;
                    }
                }
            }
        }catch(Exception e){
            ConsoleTool.cls();
            e.printStackTrace();
        }
    }
}

class Bullet extends Role{
    int dir, dx, dy;
    public Bullet(Map map, char name, int color, int cycle, int dir){
        super(map, name, color, cycle);
        if(dir<0 || dir >3) System.err.println("dir should between 0 to 3");
        this.dir = dir;
        dx=0;
        dy=0;
    }
    @Override
    public void run(){
        try {
            switch(dir){
                case 0://up
                    dy=-1;
                    break;
                case 1://down
                    dy=1;
                    break;
                case 2://left
                    dx=-1;
                    break;
                case 3://right
                    dx=1;
                    break;
                default:
                    break;
            }
            int wordCount=0;
            while (run) {
                Thread.sleep(cycle);
                synchronized (Game.lock) {
                    int preX = x, preY = y;
                    if (!map.ground[y+dy][x+dx].isBlock && map.ground[y+dy][x+dx].regestedRole==null){
                        color++;
                        x+=dx;
                        y+=dy;
                        if (preX != x || preY != y) {
                            map.ground[preY][preX].regestedRole = null;
                            map.ground[y][x].regestedRole = this;
                        }
                    }else{
                        map.delete(this);
                    }
                }
            }
        }catch(Exception e){
            ConsoleTool.cls();
            e.printStackTrace();
        }
    }
}